﻿using Mengsk.ProxyDelivery.Domain;
using Mengsk.ProxyDelivery.Print.Domain.PrintDataFormatters;
using System;
using System.Collections.Generic;
using System.Diagnostics;
using System.Drawing;
using System.Linq;
using System.Text;
using System.Threading;
using System.Windows;
using System.Windows.Documents;
using System.Windows.Media;
using System.Windows.Media.Imaging;

namespace Mengsk.ProxyDelivery.Print.Domain
{
    class OrderPrintDocument : DocumentPaginator, IDocumentPaginatorSource
    {
        private PrintTemplate template = null;

        private int lastPrintPage = 0;

        public List<Order> Orders { get; private set; }

        public List<Order> SourceOrders { get; set; }

        public event Action<OrderPrintDocument, Order> PrintStarting;

        public event Func<OrderPrintDocument, Order, bool> CanPrint;

        public OrderPrintDocument(Order[] orders, PrintTemplate template)
        {
            this.Orders = new List<Order>();
            this.Orders.AddRange(orders);
            this.SourceOrders = this.Orders.ToArray().ToList();
            this.template = template;
            this.PageSize = new System.Windows.Size(template.Width, template.Height);
        }

        private static void WirteLog(String content)
        {
            content = DateTime.Now + ":" + content + Environment.NewLine;
            Debug.WriteLine(content);
        }

        public override DocumentPage GetPage(int pageNumber)
        {
            if (this.PrintStarting != null)
            {
                this.PrintStarting(this, this.Orders[pageNumber]);
            }

            DrawingVisual dv = new DrawingVisual() { };
            var rendor = dv.RenderOpen();
            rendor.DrawRectangle(System.Windows.Media.Brushes.White, null, new Rect(this.PageSize));
            foreach (var printItem in this.template.Items)
            {
                object data = PrintDataFormatterManager.Format(this.template, printItem, this.Orders[pageNumber]);
                if (data == null)
                {
                    continue;
                }
                if (data is string)
                {
                    string text = data as string;
                    FormattedText fText = new FormattedText(text, Thread.CurrentThread.CurrentUICulture, System.Windows.FlowDirection.LeftToRight, new Typeface(printItem.FontName), printItem.FontSize, System.Windows.Media.Brushes.Black);
                    fText.SetFontFamily(printItem.FontName);
                    fText.MaxLineCount = 99;
                    fText.MaxTextHeight = printItem.Height;
                    fText.MaxTextWidth = printItem.Width;
                    fText.SetFontWeight(FontWeight.FromOpenTypeWeight(10));
                    rendor.DrawText(fText, new System.Windows.Point(printItem.X + template.XOffset, printItem.Y + template.YOffset));
                }
                else if (data is Bitmap)
                {
                    var image = data as Bitmap;
                    var bs = System.Windows.Interop.Imaging.CreateBitmapSourceFromHBitmap(image.GetHbitmap(), IntPtr.Zero, Int32Rect.Empty, BitmapSizeOptions.FromWidthAndHeight((int)printItem.Width, (int)printItem.Height));
                    rendor.DrawImage(bs, new Rect(printItem.X + template.XOffset, printItem.Y + template.YOffset, printItem.Width, printItem.Height));
                }
                else if (data is BitmapSource)
                {
                    var bs = data as BitmapSource;
                    rendor.DrawImage(bs, new Rect(printItem.X + template.XOffset, printItem.Y + template.YOffset, printItem.Width, printItem.Height));
                }
                else
                {
                    throw new Exception("无法识别的输出类型:" + data.GetType().FullName);
                }
            }
            rendor.Close();
            DocumentPage page = new DocumentPage(dv, this.PageSize, new Rect(this.PageSize), new Rect(this.PageSize));
            return page;
        }

        public override bool IsPageCountValid
        {
            get
            {
                //WirteLog("Calling IsPageCountValid...");
                return true;
            }
        }

        public override int PageCount
        {
            get
            {
                //WirteLog("Calling PageCount...");
                if (this.CanPrint != null && this.lastPrintPage < this.Orders.Count)
                {
                    while (this.lastPrintPage < this.Orders.Count)
                    {
                        Order or = this.Orders[this.lastPrintPage];
                        //取消打印该项
                        if (this.CanPrint(this, or) == false)
                        {
                            this.Orders.Remove(or);
                        }
                        else
                        {
                            this.lastPrintPage++;
                            break;
                        }
                    }
                }

                return Orders.Count;
            }
        }

        public override System.Windows.Size PageSize
        {
            get;
            set;
        }

        public override IDocumentPaginatorSource Source
        {
            get { return this; }
        }

        public DocumentPaginator DocumentPaginator
        {
            get { return this; }
        }
    }
}
